package com.wenzheng.mybatisplus.util;

import com.baomidou.mybatisplus.core.conditions.query.*;
import com.baomidou.mybatisplus.core.toolkit.*;
import com.baomidou.mybatisplus.extension.plugins.pagination.*;

import java.io.*;
import java.util.*;

/**
 **/
public class PageModel<T> implements Serializable {

	private Page<T> page = null;

	private QueryWrapper<T> queryWrapper;


	/**
	 * 格式化 数据
	 * @param pageNum: pageNum
	 * @param pageSize :pageSize
	 * @param params :params
	 */
	private static <T> PageModel<T> getPageModel(Integer pageNum, Integer pageSize, Map<String, Object> params) {
		PageModel<T> pageModel = new PageModel<>();
		pageModel.setPage(new Page<>(pageNum, pageSize));
		MapUtil.cleanNull(params);
		return pageModel;
	}

	/**
	 * 不指定查询字段
	 * @param pageNum：page
	 * @param pageSize： 分页大小
	 * @param params： 查询条件规则
	 * @return PageModel
	 * {@see addCondition(Map < String, Object > param, QueryWrapper queryWrapper) }
	 */
	public static <T> PageModel<T> createQueryWrapper(Integer pageNum, Integer pageSize, Map<String, Object> params) {
		if (params == null) {
			params = new HashMap<>(1);
		}
		PageModel<T> pageModel = getPageModel(pageNum, pageSize, params);
		pageModel.setQueryWrapper(PageModel.addCondition(params, new QueryWrapper<>()));
		return pageModel;
	}

	/**
	 * 不指定查询字段
	 * 根据map 获取查询条件
	 * @param params： 查询条件规则
	 * @return PageModel
	 * {@see addCondition(Map < String, Object > param, QueryWrapper queryWrapper) }
	 */
	public static <T> QueryWrapper<T> createQueryWrapper(Map<String, Object> params) {
		if (params == null) {
			params = new HashMap<>(1);
		}
		PageModel<T> pageModel = getPageModel(0, 10, params);
		pageModel.setQueryWrapper(PageModel.addCondition(params, new QueryWrapper<>()));
		return pageModel.getQueryWrapper();
	}


	/**
	 * 指定查询字段
	 * @param pageNum：page
	 * @param pageSize： 分页大小
	 * @param params： 查询条件规则
	 * @return PageModel
	 * {@see addCondition(Map < String, Object > param, QueryWrapper queryWrapper) }注释的规则
	 * 调用方式 ce.page(PageModel.createQueryWrapper(pageNum, pageSize, sort, null, "32","43","4565");
	 */
	public static <T> PageModel<T> createQueryWrapper(Integer pageNum, Integer pageSize, Map<String, Object> params, String... showParams) {
		if (params == null) {
			params = new HashMap<>(0);
		}
		PageModel<T> pageModel = getPageModel(pageNum, pageSize, params);
		if (showParams == null || showParams.length < 1) {
			pageModel.setQueryWrapper(PageModel.addCondition(params, new QueryWrapper<>()));
		}else {
			for (int i = 0 ; i < showParams.length ; i++) {
				showParams[i] = StringUtils.camelToUnderline(showParams[i]);
			}
			pageModel.setQueryWrapper(PageModel.addCondition(params, new QueryWrapper<T>()).select(showParams));
		}
		return pageModel;
	}

	/**
	 * 指定查询字段
	 * @param pageNum：page
	 * @param pageSize： 分页大小
	 * @param params： 查询条件规则
	 * @return PageModel
	 * {@see addCondition(Map < String, Object > param, QueryWrapper queryWrapper) }
	 * 调用方式 ce.page(PageModel.createQueryWrapper(pageNum, pageSize, sort, null, Arrays.asList("22", "ds");
	 */
	public static <T> PageModel<T> createQueryWrapper(Integer pageNum, Integer pageSize, Map<String, Object> params, List<String> showParams) {
		if (params == null) {
			params = new HashMap<>(1);
		}
		String[] showParamsArr = showParams.toArray(new String[0]);
		for (int i = 0 ; i < showParamsArr.length ; i++) {
			showParamsArr[i] = StringUtils.camelToUnderline(showParamsArr[i]);
		}
		if (!showParams.isEmpty()) {
			return createQueryWrapper(pageNum, pageSize, params, showParamsArr);
		}else {
			return createQueryWrapper(pageNum, pageSize, params);
		}
	}

	/**
	 * @param param: 参数
	 * 查询规则 以name 查询为例子
	 * 准确查询 ：name
	 * 模糊查询 ：name_l
	 * notlike查询 ：name_nl
	 * in查询: name_ne
	 * not in查询: name_nin
	 * 大于查询：name_gt
	 * 大于等于：name_gte
	 * 小于查询：name_le
	 * 小于查询：name_lte
	 * 不等于: name_ne
	 * asc排序 : name_asc 作为key value 可以为任意值
	 * desc 排序: name_desc  作为key value 可以为任意值
	 * @param queryWrapper:QueryWrapper
	 */
	private static <T> QueryWrapper<T> addCondition(Map<String, Object> param, QueryWrapper<T> queryWrapper) {

		param.forEach((ka, v) -> {
			String[] ks = ka.split("_");
			String k = com.baomidou.mybatisplus.core.toolkit.StringUtils.camelToUnderline(ks[0]);
			String type = "";
			if (ks.length == 2) {
				type = ks[1];
			}

			if ("l".equals(type)) {
				queryWrapper.like(k, v);
			}else if ("gt".equals(type)) {
				queryWrapper.gt(true, k, v);
			}else if ("in".equals(type)) {
				queryWrapper.in(k, v);
			}else if ("lt".equals(type)) {
				queryWrapper.lt(k, v);
			}else if ("ne".equals(type)) {
				queryWrapper.ne(k, v);
			}else if ("nl".equals(type)) {
				queryWrapper.notLike(k, v);
			}else if ("asc".equals(type)) {
				queryWrapper.orderBy(true, true, k);
			}else if ("gte".equals(type)) {
				queryWrapper.ge(true, k, v);
			}else if ("lte".equals(type)) {
				queryWrapper.le(k, v);
			}else if ("nin".equals(type)) {
				queryWrapper.notIn(k, v);
			}else if ("desc".equals(type)) {
				queryWrapper.orderBy(true, false, k);
			}else {
				queryWrapper.eq(k, v);
			}
		});
		return queryWrapper;
	}

	public Page<T> getPage() {
		return page;
	}

	public void setPage(Page<T> page) {
		this.page = page;
	}

	public QueryWrapper<T> getQueryWrapper() {
		return queryWrapper;
	}

	public void setQueryWrapper(QueryWrapper<T> queryWrapper) {
		this.queryWrapper = queryWrapper;
	}
}
